package com.imooc.SmartChargeStation.netty.server.handlers;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelId;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ConcurrentHashMap;

/**
 * WebSocketFrame数据帧格式
 */
@Slf4j
public class ImoocWebSocketInboundHandler extends SimpleChannelInboundHandler<WebSocketFrame> {

    // 保存所有连接的channel
    //用于发信息给指定用户
    private static ConcurrentHashMap channelMap = new ConcurrentHashMap<String,Channel>();

    /**
     * 有新链接会触发
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        //每个客户端的一个连接
        Channel channel = ctx.channel();
        log.info(">>>>>有新的客户端连接进来: "+channel.id());
        //保存连接
        channelMap.put(channel.id().asLongText(),channel);
    }

    /**
     * 接收到websocket数据帧
     * @param ctx           the {@link ChannelHandlerContext} which this {@link SimpleChannelInboundHandler}
     *                      belongs to
     * @param msg           the message to handle
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {

        //将msg转换成字符串
        /* **********************
         *
         * WebSocketFrame包含
         * 1. TextWebSocketFrame 数据帧的内容是文本类型
         * 2.  BinaryWebSocketFrame 数据帧的内容是二进制类型
         *
         * *********************/

        //判断数据帧的内容是否文本类型
        if( msg instanceof TextWebSocketFrame) {
            //文本类型的数据的业务逻辑会在这里处理
            String message = ((TextWebSocketFrame) msg).text();
            log.info(">>>>>收到channel id为"+ctx.channel().id()+"的消息: "+message);
        }else if( msg instanceof BinaryWebSocketFrame) {
            //(Protobuf序列数据)二进制类型的数据业务逻辑会在这里处理


        }
    }

    /**
     * 连接断开时候触发
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel =  ctx.channel();
        log.info(">>>>>有客户端断开连接: "+channel.id());
        //删除保存的Channel
        channelMap.remove(channel.id().asLongText());
    }
}
